package com.ys.day29.Reflect.p7使用Reflect直接创建对象;

import com.ys.day29.Reflect.p6Reflect与Constructor对象.Student;

import java.lang.reflect.Constructor;

/**
 * 描述: P2使用构造器签名创建创建对象
 *
 * @author CodeYang
 * @version 2021/1/11 21:31
 */
public class P2使用构造器签名创建创建对象 {

    public static void main(String[] args) {

        function01();
        function02();

    }

    /**
     * 通过构造器签名创建有参数对象
     *  场景：通过构造器签名创建有参数对象
     *  * 步骤：
     *  * 1 反射入口
     *  * 2 调用Class对象的getConstructor(Class...params)方法
     *  * 3 设置参数类型和参数实际的值
     *  * 4 调用Constructor对象的newInstance(Object...objs)方法创建对象
     */
    private static void function02() {
        // 1反射入口
        Class<Student> aClass = Student.class;
        // 2设置参数列表  反射技术是JVM级别的技术, 不能自动转换包装类,必须严格的要求 class对象 int 与 Integer... 不相兼容

        Class<?>[] param ={int.class,String.class,String.class};
        // 3 设置参数列表 实际值
        Object[] values = {123,"小王","男"};
        try {
            // 此时根据参数获取构造方法签名，只指定了参数类型，并没有指定参数名称，参数实际的值在调用newInstance(Object...objs)方法时指定
            Constructor<Student> constructor = aClass.getDeclaredConstructor(param);
            Student student = constructor.newInstance(values);
            System.out.println(student);
            // 运行时异常：java.lang.IllegalArgumentException: wrong number of arguments
            // 构造方法签名是有参的，不能创建无参对象，参数类型和实际的值必须匹配
            // Student stu = structor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     *  * 场景：通过构造器签名创建对象
     *  * 步骤：
     *  * 1反射入口
     *  * 2获取Class对象的构造器签名
     *  * 3调用Constructor的newInstance()方法创建对象
     */
    private static void function01() {

        Class<Student> studentClass = Student.class;


        try {
            // 获得无参Student构造器签名
            Constructor<Student> constructor = studentClass.getConstructor();
            // newInstance()方法是构造器签名Constructor的成员方法，该方法表示通过反射新创建一个Student的实例
            Student student = constructor.newInstance();
            System.out.println(student);


        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}
